package gri_portal_config;

use xml_helper;
use Data::Dumper;

my $error="";

# validate_xml is actually a class sub rather than instance sub

sub validate_xml {
my $xml=shift;

	new("",undef,$xml);
	if($error eq "") {
		return undef;
	}
	return $error;
}

sub new {
my $self={};
shift;
my $f=shift;

	$error="";
	$self->{xml_helper}=new xml_helper();
	my $d=""; my $fd;
	if(defined($f)) {
		if(! -f $f) {
			$f.=".xml";
		}
		$self->{filename}=$f;
		if(!open($fd,$f)) {
			$error="Can not open file '$f' : $!";
			return(undef);
		}
		$d=join("",<$fd>);
		close($fd);
	} else {
		$d=shift;
		$self->{filename}="stdin";
	}
	$self->{raw_xml}=$d;
	my $x=$self->{xml_helper}->parse($d);
	if(! $x) {
	print STDERR "HERE!!!\n";
		$error="Unable to parse XML: " . xml_helper::error();
		return undef;
	}

	# Check the data is in the format we expect.

	my ($data,$attrs,$elements)=$self->{xml_helper}->get_element("");
	if(!defined($data)) {
		$error="Invalid data to parse [top level]";
		return(undef);
	}
	if(scalar(@$elements)!=1) {
		$error="More than 1 top level element!";
		return(undef);
	}
	if($elements->[0] ne "|gri_portal_config#0") {
		$error="Top level element is not 'gri_portal_config'";
		return(undef);
	}
	($data,$attrs,$elements)=$self->{xml_helper}->get_element("gri_portal_config#0");
	if(!defined($data)) {
		$error="Invalid data to parse [gri_portal_config#0]";
		return(undef);
	}
	#################################################################
	# We expect the title and reports elements to be here - abort	#
	# if not.							#
	#################################################################
	if(! grep {$_ eq "gri_portal_config#0|title#0"} @$elements) {
		$error="Missing 'title' element.";
		return(undef);
	}
	if( (! grep {$_ eq "gri_portal_config#0|reports#0"} @$elements) && 
		(! grep {$_ eq "gri_portal_config#0|meta_reports#0"} @$elements) ) {
		$error="Missing 'reports' or 'meta_reports' element in '$f'.";
		return(undef);
	}
	for my $cent (@$elements) {
		if(! grep {$_ eq $cent} (
			"gri_portal_config#0|reports#0",
			"gri_portal_config#0|meta_reports#0",
			"gri_portal_config#0|title#0",
			"gri_portal_config#0|users#0",
			"gri_portal_config#0|owners#0",
			"gri_portal_config#0|voters#0",
			"gri_portal_config#0|concur_count#0",
			"gri_portal_config#0|template#0")) {
			$error="Unexpected element '$cent' found.";
			return(undef);
		}
	}
	#################################################################
	# Get the data and store in the object for easy reference.	#
	#################################################################
	my ($data2,$attrs2,$elements2)=$self->{xml_helper}->get_element("gri_portal_config#0|title#0");
	$self->{title}=$data2;
	for my $cl ("meta_reports","reports","users","owners","voters") {
		($data2,$attrs2,$elements2)=$self->{xml_helper}->get_element("gri_portal_config#0|$cl#0");
		if(defined($data2)) {
			$data2 =~ s/\s//g;
			$data2 =~ s/\n//g;
			$self->{$cl}=[split(/,/,$data2)];
		}

	}
	if(grep {$_ eq "gri_portal_config#0|template#0"} @$elements) {
		($data2,$attrs2,$elements2)=$self->{xml_helper}->get_element("gri_portal_config#0|template#0");
		$self->{template}=$data2;
	} else {
		$self->{template}=undef;
	}
	if(grep {$_ eq "gri_portal_config#0|concur_count#0"} @$elements) {
		($data2,$attrs2,$elements2)=$self->{xml_helper}->get_element("gri_portal_config#0|concur_count#0");
		$self->{concur_count}=$data2;
	} else {
		$self->{concur_count}=undef;
	}
	if(!exists($self->{meta_reports})) {
		$self->{meta_reports}=[];
	}
	if(!exists($self->{reports})) {
		$self->{reports}=[];
	}
	bless($self);
	return $self;
}

sub get_details {
my $self=shift;

	my %d=(title => $self->{title});
	for $cl ("filename","template","users","meta_reports","reports","owners","voters","concur_count") {
		if(exists($self->{$cl})) {
			$d{$cl}=$self->{$cl};
		}
	}
	return {%d};
}

sub get_title {
my $self=shift;
	return $self->{title};
}

sub set_title {
my $self=shift;
my $title=shift;

	$self->{title}=$title;
}
sub get_reports {
my $self=shift;
my $as_list=shift;

	if(defined($as_list) && $as_list) {
		return (@{$self->{reports}});
	}
	return $self->{reports};
}

sub get_meta_reports {
my $self=shift;
my $as_list=shift;

	if(defined($as_list) && $as_list) {
		return (@{$self->{meta_reports}});
	}
	return $self->{meta_reports};
}
sub get_template {
my $self=shift;
	return $self->{template};
}

sub get_users {
my $self=shift;
	return $self->{users};
}

# To set the reports send across a string of report filenames

sub set_users {
my $self=shift;
my $users=shift;

	if(ref($users)) {
		$self->{users}=[@$users];
	} else {
		$self->{users}=[split(/,/,$users)];
	}
}

sub set_reports {
my $self=shift;
my $reps=shift;

	$self->{reports}=$reps;
}

sub set_meta_reports {
my $self=shift;
my $reps=shift;

	$self->{meta_reports}=$reps;
}

sub write_file {
my $self=shift;
my $filename=$self->{filename};
my $aa=new xml_helper();

	if(-f "$filename.tmp") {
		unlink("$filename.tmp") or return(0,"Unable to delete temporary file.");
	}
	my $fd;
	open($fd,">$filename.tmp");
	return(0,"Unable to open '$filename.tmp' for writing: $!") if !defined($fd);
	if(! print $fd "<?xml version=\"1.0\" standalone=\"yes\"?>
<gri_portal_config>
	<title>" . $aa->string_to_xml($self->{title}) . "</title>\n") {
		return(0,"Failed to write to file '$filename.tmp': $!");
	}
	if(defined($self->{template})) {
		if(! print $fd "\t<template>" . $aa->string_to_xml($self->{template}) . "</template>\n") {
			return(0,"Failed to write to file '$filename.tmp': $!");
		}
	} else {
		if(! print $fd "\t<template></template>\n") {
			return(0,"Failed to write to file '$filename.tmp': $!");
		}
	}
	my $ul="";
	if(defined($self->{users})) {
		$ul=join(",",@{$self->{users}});
		if(! print $fd "<users>$ul</users>\n") {
			return(0,"Failed to write to file '$filename.tmp': $!");
		}
	}

	# Write out reports and meta_reports...
	my $reps=join(",",@{$self->{reports}});
	if(! print $fd "\t<reports>" . $aa->string_to_xml($reps) . "</reports>\n") {
		return(0,"Failed to write to file '$filename.tmp': $!");
	}
	$reps=join(",",@{$self->{meta_reports}});
	if(! print $fd "\t<meta_reports>" . $aa->string_to_xml($reps) . "</meta_reports>\n") {
		return(0,"Failed to write to file '$filename.tmp': $!");
	}
	if(! print $fd "</gri_portal_config>\n") {
		return(0,"Failed to write to file '$filename.tmp': $!");
	}
	close($fd);

	unlink($filename) or return (0,"Unable to remove file '$filename'.");
	rename("$filename.tmp",$filename) or return(0,"Unable to rename '$filename.tmp' to '$filename' : $!");
	return(1,undef);
}

sub error {
	return $error;
}

sub get_xml {
my $self=shift;

	return $self->{raw_xml};
}

sub delete {
my $self=shift;

	if($self->{filename} eq "stdin") {
		return(0);
	}
	if(unlink($self->{filename})) {
		return(1);
	}
	return 0;
}

1;

